#include "pch.hpp"
#include "Placement.hpp"
#include "Widget.hpp"

using namespace Engine;
using namespace Engine::Ui;




Border::Type Border::fromString(QString border)
{
	if(border == "tl")        return TopLeft;
	else if(border == "t")    return Top;
	else if(border == "tr")   return TopRight;
	else if(border == "r")    return Right;
	else if(border == "br")   return BottomRight;
	else if(border == "b")    return Bottom;
	else if(border == "bl")   return BottomLeft;
	else if(border == "l")    return Left;
	else if(border == "none") return Center;
	else BOOSTEXT_THROW(invalid_value_exception(border));
}
///////////////////////////////////////////////////////////////////////////////////////////////////




Placement::Placement(intsize2 size, intsize2 reserved)
	: pos((reserved.width - size.width) / 2, (reserved.height - size.height) / 2)
	, size(size)
	, reserved(reserved)
{}
///////////////////////////////////////////////////////////////////////////////////////////////////

Placement Placement::centered(const boost::shared_ptr<Widget>& widget, Type vertPlacement, Type horPlacement, int height, int width)
{
	intsize2 minSize = widget->minimumSize();
	intsize2 maxSize = widget->maximumSize();

	int2 childPos;
	intsize2 childSize;
	intsize2 reservedSize;


	switch(vertPlacement)
	{
	case Minimum:
		childSize.height    = minSize.height;
		reservedSize.height = minSize.height;
		break;
	case MinimumCentered:
		childSize.height    = minSize.height;
		reservedSize.height = height;
		break;
	case OptimumCentered:
		childSize.height    = math::clamp(height, minSize.height, maxSize.height);
		reservedSize.height = height;
		break;
	case Maximum:
		childSize.height    = maxSize.height;
		reservedSize.height = maxSize.height;
		break;
	}

	switch(horPlacement)
	{
	case Minimum:
		childSize.width    = minSize.width;
		reservedSize.width = minSize.width;
		break;
	case MinimumCentered:
		childSize.width    = minSize.width;
		reservedSize.width = width;
		break;
	case OptimumCentered:
		childSize.width    = math::clamp(width, minSize.width, maxSize.width);
		reservedSize.width = width;
		break;
	case Maximum:
		childSize.width    = maxSize.width;
		reservedSize.width = maxSize.width;
		break;
	}

	return Placement(childSize, reservedSize);
}
///////////////////////////////////////////////////////////////////////////////////////////////////

uint32 Placement::remainingWidgets(const Map& placed)
{
	uint32 num = 0;

	foreach(const Pair& p, placed)
	{
		if(!p.second)
			++num;
	}

	return num;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
